﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using Engine.Base;
using Engine.Game;
using Engine.Messaging;
using Engine.Input;
using Engine.Rendering;

namespace Engine
{
    public class Engine : IDisposable
    {
        #region Properties
        private List<ISubSystem> SubSystems { get; set; }

        public RenderingSystem RenderingSystem { get; private set; }
        public MessageSystem MessageSystem { get; private set; }
        public InputHandlerSystem InputHandlerSystem { get; private set; }
        //public GameStateManager GameStateManager { get; private set; }
        public IGameManager GameManager { get; private set; }
        public EngineGame Game { get; private set; }
        #endregion // Properties


        #region Constructors
        private Engine(IGameManager gameManager)
        {
            RenderingSystem = new RenderingSystem();
            MessageSystem = new MessageSystem();
            InputHandlerSystem = new InputHandlerSystem(MessageSystem);


            //GameStateManager = new GameStateManager();
            GameManager = gameManager;


            this.SubSystems = new List<ISubSystem>();
            this.SubSystems.Add(RenderingSystem);
            this.SubSystems.Add(MessageSystem);
            this.SubSystems.Add(InputHandlerSystem);
            //this.SubSystems.Add(GameStateManager);
            this.SubSystems.Add(GameManager);
        }
        #endregion // Constructors


        #region Methods
        public void Run()
        {
            SubSystems.ForEach(sys => sys.Start());

            Logger.Debug("Starting game");
            using (Game = new EngineGame(this))
            {
                Game.Run();
            }
            Logger.Debug("Game Ended");
        }
        #endregion // Methods









        public void Dispose()
        {
            for (int i = SubSystems.Count - 1; i >= 0; --i)
                SubSystems[i].Stop();
            SubSystems.Clear();
        }


        #region STATIC
        public static Engine TheEngine { get; private set; }
        public static void StartAndRun(IGameManager gameManager)
        {
            using (TheEngine = new Engine(gameManager))
            {
                TheEngine.GameManager.Engine = TheEngine;
                TheEngine.Run();
            }
        }

        private static ILog Logger { get; set; }
        static Engine()
        {
            Logger = LogManager.GetLogger(typeof(Engine));
        }
        #endregion // STATIC

    }
}
